/*** Class Name: ifulfillWebService
* Author: Accenture      
* Requirement/Project Name: iFULFILL
* Requirement/Project Description:SFDC should verify that the CSS system is not down prior to sending an TaskHistory outbound message,Notes Outbound Message.
* If the system is down then Store the error message(messages will be provided by SIL),stackTrace in the TaskHistory Object.
* If the System is up then store the success message into the TaskHistory object.
*
* **/
global without sharing class ifulfillWebService{

    static String errorMessage=null;
    static String statusCode=null;
    static String stackTrace=null;
    static String lastModifiedDate =null;
    static String endPointURL =null;
    static String bodyData =null;
    
    /*
    * This method fetch the taskHistory ids and filter the In-Region records and send the request to the SIL 
    * Process the data based upon the response back  from the SIL and update the taskhistory record.
    */
    @future(callout=true)
    public static void processRequest(Set<Id> taskHistoryIds){
        AppEndPoints__c appEndPoints = AppEndPoints__c.getInstance();
        String []responseArray;
        String autoNotes='';
        List<Fulfillment_Step_History__c> restAPIReponseTaskHistoryList = new List<Fulfillment_Step_History__c>();
        List<Fulfillment_Step_History__c> taskHistoryList =[select Id,AutoNotes__c,CreatedByID,Fullfilment_Item__c,LastModifiedDate,Fullfilment_Item__r.Region__c from Fulfillment_Step_History__c where id in :taskHistoryIds];
        try{ 
           for(Fulfillment_Step_History__c FSH:taskHistoryList){  
             if(FSH !=null && FSH.Fullfilment_Item__r.Region__c.contains('In-Region')){ 
             
                if(FSH.AutoNotes__c !=null){
                   autoNotes=FSH.AutoNotes__c + '';
                 }   
       
                lastModifiedDate= FSH.LastModifiedDate.format('MM/dd/yyyy');
                endPointURL=appEndPoints.workflowCompleteURL__c+'/UpdateIRFulfillmentTaskHistory?AutoNotes='+EncodingUtil.urlEncode(autoNotes,'UTF-8')+'&CreatedById='+FSH.CreatedByID+'&FullfilmentItem='+FSH.Fullfilment_Item__c+'&Id='+FSH.ID+'&LastModifiedDate='+lastModifiedDate;                  
                bodyData='AutoNotes='+EncodingUtil.urlEncode(autoNotes,'UTF-8')+'&CreatedById='+FSH.CreatedByID+'&FullfilmentItem='+FSH.Fullfilment_Item__c+'&Id='+FSH.ID+'&LastModifiedDate='+lastModifiedDate;
                System.debug('endPointURL  ->'+endPointURL);                
                responseArray =invokeRestAPICall(endPointURL,'TaskHistory',bodyData); 
                System.debug('responseArray --->'+responseArray); 
                if(responseArray[0] !=null && responseArray[0].equals('0')){ 
                    FSH.Delivery_Status__c=IfullfillTextConstant.FI_PR_DELIVERY_SUCCESS_STATUS;
                    FSH.Status_Code__c=responseArray[0];
                    restAPIReponseTaskHistoryList.add(FSH);                 
                }else{
                     FSH.Delivery_Status__c=IfullfillTextConstant.FI_PR_DELIVERY_FAILED_STATUS;
                     FSH.Status_Code__c=responseArray[0];
                     FSH.Error_Message__c=responseArray[1];
                     FSH.Error_Stack__c=responseArray[2];
                     restAPIReponseTaskHistoryList.add(FSH);                     
                } 
              }                 
           }
           System.debug('restAPIReponseTaskHistoryList---->'+restAPIReponseTaskHistoryList);
           if(restAPIReponseTaskHistoryList.size()>0){
               update restAPIReponseTaskHistoryList;
            }        
        }catch(Exception e){
            System.debug('Exception is restAPIReponseTaskHistoryList'+e);
        }     
    }
    /*
    * This method fetch the Notes ids and filter the In-Region records and send the request to the SIL 
    * Process the data based upon the response back  from the SIL and update the taskhistory record.
    */
     @future(callout=true)
    public static void processNotesRequest(Set<Id> notesIds){
        AppEndPoints__c appEndPoints = AppEndPoints__c.getInstance();
        List<Notes__c> restAPINotesList = new List<Notes__c>();
        String []responseArray;
        String notesData='';
        List<Notes__c> noteList=[select Id,CreatedByID,Fullfilment_Notes__c,LastModifiedDate,Notes__c,Fullfilment_Notes__r.Region__c from Notes__c  where id in :notesIds];
       try{ 
         for(Notes__c notes:noteList){
              if(notes !=null && notes.Fullfilment_Notes__r.Region__c.contains('In-Region')){     
                if(notes.Notes__c!=null)
                   notesData=notes.Notes__c+'';                 
                lastModifiedDate= notes.LastModifiedDate.format('MM/dd/yyyy');
                endPointURL=appEndPoints.workflowCompleteURL__c+'/UpdateIRFulfillmentNote?CreatedById='+notes.CreatedByID+'&FullfilmentNotes='+notes.Fullfilment_Notes__c+'&Id='+notes.ID+'&LastModifiedDate='+lastModifiedDate+'&Notes='+EncodingUtil.urlEncode(notesData,'UTF-8');                  
                bodyData='CreatedById='+notes.CreatedByID+'&FullfilmentNotes='+notes.Fullfilment_Notes__c+'&Id='+notes.ID+'&LastModifiedDate='+lastModifiedDate+'&Notes='+EncodingUtil.urlEncode(notesData,'UTF-8');
                responseArray =invokeRestAPICall(endPointURL,'Notes',bodyData); 
                System.debug('responseArray --->'+responseArray); 
                if(responseArray[0] !=null && responseArray[0].equals('0')){ 
                    notes.Delivery_Status__c=IfullfillTextConstant.FI_PR_DELIVERY_SUCCESS_STATUS;
                    notes.Status_Code__c=responseArray[0];
                    restAPINotesList.add(notes);                
                }else{
                     notes.Delivery_Status__c=IfullfillTextConstant.FI_PR_DELIVERY_FAILED_STATUS;
                     notes.Status_Code__c=responseArray[0];
                     notes.Error_Message__c=responseArray[1];
                     notes.Error_Stack__c=responseArray[2];
                     restAPINotesList.add(notes);                    
                } 
             }                  
          } 
           System.debug('restAPINotesList --->'+restAPINotesList);
           if(restAPINotesList.size()>0){
               update restAPINotesList;
           }
           
         }catch(Exception e){
             
             System.debug('Exception in webservice'+e);
         }    
    }
    /*
    * This method send the request to the SIL and receive the response back and prepare the response in array .
    */        
    
    public static String[] invokeRestAPICall(String endPoint,String callFrom,String setBodyData){
        errorMessage=null;
        statusCode=null;
        stackTrace=null;
        String []responseData =new String[3];
        HttpRequest req= new HttpRequest();
        req.setMethod('POST');
        req.setEndpoint(endpoint);
        req.setTimeout(20000);  
        req.setHeader('Content-Length','1024');  
        if(callFrom.equals('TaskHistory')){           
            req.setBody(setBodyData);
        }else if(callFrom.equals('Notes')){
           req.setBody(setBodyData);
        }   
        System.debug('Req message -->'+req.getBody());
                
        try{  
           Http http = new Http();
           HttpResponse res= http.send(req);
           //connected to the SIL
           if(res.getStatusCode() == 200){
            System.debug('response-->'+res.toString());
            String responseXML = res.getBody();
            System.debug('responseXML ---->'+responseXML);
        
            Dom.Document domDoc = new Dom.Document();          
            domDoc.load(responseXML);                
            Dom.XMLNode address = domDoc.getRootElement();   
            
            if(address.getChildElement('ErrorMessage', 'http://sil.service')!=null){     
                errorMessage= address.getChildElement('ErrorMessage', 'http://sil.service').getText();
            }
            if(address.getChildElement('StatusCode', 'http://sil.service')!=null){     
               statusCode = address.getChildElement('StatusCode', 'http://sil.service').getText();
            } 
            if(address.getChildElement('StackTrace', 'http://sil.service')!=null){     
               stackTrace= address.getChildElement('StackTrace', 'http://sil.service').getText();     
            }                         
            System.debug('errorMessage -->'+errorMessage);
            System.debug('statusCode -->'+statusCode);
            System.debug('stackTrace -->'+stackTrace);
            System.debug('response statuscode'+res.toString());            
            
           }else if(res.getStatusCode() == 404){            
              statusCode ='1';              
              errorMessage='Unable to contact CSS.Please contact System Administrator'; 
              stackTrace='Unable to contact CSS.Please contact System Administrator';                                   
           } 
       }catch(CalloutException e){           
           system.debug('exception is'+e+'exption contains--->'+e.getMessage().contains('Read timed out'));
           if(e.getMessage().contains('Read timed out')){
              statusCode ='1';
              errorMessage='Timeout error Occured.Please try again'; 
              stackTrace='Timeout error Occured.Please try again'; 
            }else{                       
                statusCode ='1';              
                errorMessage='Unable to contact CSS.Please contact System Administrator'; 
                stackTrace='Unable to contact CSS.Please contact System Administrator';  
             }   
       } 
       responseData[0]=statusCode;
       responseData[1]=errorMessage;
       responseData[2]=stackTrace;  
       
       System.debug('responseData ****'+responseData);
       return responseData;
    }
  

}